﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text.RegularExpressions;
using System.Web.Hosting;

using Telerik.Cms;
using MigrationExportService;

namespace Telerik.Sitefinity.Services.Migration
{
	public partial class MigrationExportService : IMigrationExportService
	{
		private enum MigrationMasterPageStatus
		{
			Primary,
			NotPrimary
		};

		private void GetUserControls(string fileContent, List<MigrationUserControl> userControlsList)
		{
			MatchCollection registerTags = Regex.Matches(fileContent, @"<%@\s*Register.*?Src=""?([\w\._\/~-]*)""?.*?%>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
			foreach (Match registerTag in registerTags)
			{
				string userControlPath = registerTag.Groups[1].Value;
				string userControlPathResolved = HostingEnvironment.MapPath(userControlPath);
				string userControlContents = MigrationUtils.GetSafeTextFileContents(userControlPathResolved);
				string userControlCodeBehindContents = String.Empty;

				MigrationUserControl muc = new MigrationUserControl();

				Match codeBehindMatch = Regex.Match(userControlContents, @"<%@\s*Control.*?CodeFile=""?([\w\._\/~-]*)""?.*?%>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
				if (codeBehindMatch.Success)
				{
					var codeBehindFileName = codeBehindMatch.Groups[1].Value;
					muc.AscxCodeBehindFileName = codeBehindFileName;
					var codeBehindFullPath = Path.GetDirectoryName(userControlPathResolved) + "\\" + codeBehindFileName;
					userControlCodeBehindContents = MigrationUtils.GetSafeTextFileContents(codeBehindFullPath);
				}

				muc.AscxFilePath = userControlPath;
				muc.AscxFileContent = userControlContents;
				muc.AscxFileCondeBehindContent = userControlCodeBehindContents;

				userControlsList.Add(muc);

				GetUserControls(userControlContents, userControlsList);
			}
		}

		private void GetMasterPages(string masterPagePath, List<MigrationMasterPage> masterPagesList, MigrationMasterPageStatus isPrimary)
		{
			if (!String.IsNullOrEmpty(masterPagePath))
			{
				var masterPageName = masterPagePath.Replace("~/App_Master/", String.Empty);

				string masterPageContents = MigrationUtils.GetSafeTextFileContents(HostingEnvironment.MapPath("~/App_Master/" + masterPageName));

				MigrationMasterPage mmp = new MigrationMasterPage();
				mmp.MasterPageName = masterPageName;
				mmp.MasterPagePath = masterPagePath;
				mmp.MasterPageContents = masterPageContents;
				mmp.IsPrimary = isPrimary == MigrationMasterPageStatus.Primary ? true : false;

				// Find any user controls (ascx) and export them as well
				GetUserControls(masterPageContents, mmp.UserControls);

				masterPagesList.Add(mmp);

				Match match = Regex.Match(masterPageContents, @"<%@ Master.*?MasterPageFile=""(.*?)"".*?%>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
				if (match.Success)
				{
					GetMasterPages(match.Groups[1].Value, masterPagesList, MigrationMasterPageStatus.NotPrimary);
				}
			}
		}

		public Message GetTemplatesList()
		{
			List<MigrationItemContentDefinition> output = new List<MigrationItemContentDefinition>();

			IDictionary<string, CmsProvider> cmsProviders = CmsManager.Providers;

			foreach (KeyValuePair<string, CmsProvider> cmsProvider in cmsProviders)
			{
				string providerName = cmsProvider.Key;

#if VERSION_BELOW_SP3
				CmsManager cmsManager = new CmsManager();
#else
				CmsManager cmsManager = new CmsManager(providerName);
#endif

				IList templates = cmsManager.GetTemplates();

				foreach (IPageTemplate template in templates)
				{
					var micd = new MigrationItemContentDefinition();
					micd.Id = template.ID;
					micd.ProviderName = providerName;

					output.Add(micd);
				}
			}

			MessageVersion ver = OperationContext.Current.IncomingMessageVersion;
			return Message.CreateMessage(ver, "GetTemplatesListResponse", output);
		}

		public Message GetSingleTemplate(Message templateDefinitionParam)
		{
			MigrationItemContentDefinition param = templateDefinitionParam.GetBody<MigrationItemContentDefinition>();

#if VERSION_BELOW_SP3
			CmsManager cmsManager = new CmsManager();
#else
			CmsManager cmsManager = new CmsManager(param.ProviderName);
#endif

			IPageTemplate template = cmsManager.GetTemplate(param.Id);

			MigrationTemplate result = new MigrationTemplate();

			result.CmsProviderName = template.CmsProvider.Name;
			result.ContainsUrlSrvc = template.ContainsUrlSrvc;
			result.DateCreated = template.DateCreated;
			result.DateModified = template.DateModified;
			result.Id = template.ID;
			result.LangId = template.LangID;
#if VERSION_BELOW_SP3
			result.LastModifier = String.Empty;
#else
			result.LastModifier = template.LastModifier;
#endif
			result.Name = template.Name;
			result.Status = template.Status.ToString();
			result.Theme = template.Theme;
			result.Version = template.Version;

			// Recursively get all nested master pages used in this template
			GetMasterPages(template.MasterPage, result.MasterPages, MigrationMasterPageStatus.Primary);

			// Add the controls to the template
			GetControlsToMigrationCollection(template.Staged.Controls, result.Controls);

			MessageVersion ver = OperationContext.Current.IncomingMessageVersion;
			return Message.CreateMessage(ver, "GetSingleTemplateResponse", result);
		}
	}
}
